// Copyright (c) 2025 Huawei Device Co., Ltd.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "arkweb/chromium_ext/content/common/arkweb_user_agent_ext.h"

#if !defined(COMPONENT_BUILD)
#include "cef/ohos_cef_ext/libcef/browser/useragent/ua_push_config.h"
#endif
namespace content {

#if BUILDFLAG(ARKWEB_USERAGENT)
#if BUILDFLAG(ARKWEB_TEST)
std::atomic<bool> is_compatible_type_setted{false};
static std::string compatible_device_type;
void SetArkwebUserAgentExtStateForTest(bool is_setted) {
  is_compatible_type_setted.store(is_setted, std::memory_order_relaxed);
}

void ResetArkwebUserAgentExtStateForTest() {
  SetArkwebUserAgentExtStateForTest(false);
  compatible_device_type.clear();
}
#else
namespace {
std::atomic<bool> is_compatible_type_setted{false};
static std::string compatible_device_type;
}  // namespace
#endif

std::string GetDistVersion() {
  std::string dist_version;
  int versionPartOne;
  int versionPartTwo;
  int versionPartThree;
  std::string os_version = base::ohos::OsVersion();
  int ret = sscanf_s(os_version.c_str(), "%d.%d.%d", &versionPartOne,
                     &versionPartTwo, &versionPartThree);
  if (ret <= 0) {
    return dist_version;
  }
  base::StringAppendF(&dist_version, "%d.%d", versionPartOne, versionPartTwo);
  return dist_version;
}
void UpdateBaseOsName(std::string& base_os_name_front_str,
                       std::string& base_os_name_back_str,
                       const std::string device_type_string) {
#if !defined(COMPONENT_BUILD)
  if (ohos_user_agent::UAPushConfig::GetInstance()) {
    ohos_user_agent::OSPositionPrefsInfo defaultPrefs{"", ""};
    ohos_user_agent::OSPositionPrefsInfo os_postion_prefs =
        ohos_user_agent::UAPushConfig::GetInstance()
            ->GetLastOsPositionStr(device_type_string)
            .value_or(defaultPrefs);
    base_os_name_front_str = os_postion_prefs.front_str;
    base_os_name_back_str = os_postion_prefs.back_str;
  }
#endif
}
std::string GetOhosFullname() {
  std::string device_type_string = "Phone";
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line != nullptr) {
    if (command_line->HasSwitch(::switches::kUserAgentValue)) {
      device_type_string =
          command_line->GetSwitchValueASCII(::switches::kUserAgentValue);
    }
  }

  if (!is_compatible_type_setted) {
    compatible_device_type = base::ohos::CompatibleDeviceType();
    is_compatible_type_setted = true;
  }

  if (!compatible_device_type.empty()) {
    if (compatible_device_type == "Phone" || compatible_device_type == "PC" ||
        compatible_device_type == "Tablet") {
      LOG(DEBUG) << "compatible device type is: " << compatible_device_type;
      device_type_string = compatible_device_type;
    } else {
      LOG(DEBUG) << "unknown compatible device type: " << compatible_device_type;
    }
  }

  int32_t ohos_major_version = base::ohos::MajorVersion();
  int32_t ohos_senior_version = base::ohos::SeniorVersion();
  std::string base_os_name = base::ohos::BaseOsName();
  std::string ohos_fullname_str;
  std::string base_os_name_front_str = "";
  std::string base_os_name_back_str = "";
  UpdateBaseOsName(base_os_name_front_str, base_os_name_back_str,
                    device_type_string);
  if (base_os_name.empty() || ohos_major_version == -1 ||
      ohos_senior_version == -1) {
    std::string base_os_name_default = "OpenHarmony";
    base::StringAppendF(
        &ohos_fullname_str, "%s; %s%s%s", device_type_string.c_str(),
        base_os_name_front_str.c_str(), base_os_name_default.c_str(),
        base_os_name_back_str.c_str());
  } else {
    base::StringAppendF(
        &ohos_fullname_str, "%s; %s%s %d.%d%s", device_type_string.c_str(),
        base_os_name_front_str.c_str(), base_os_name.c_str(),
        ohos_major_version, ohos_senior_version, base_os_name_back_str.c_str());
  }
  std::string dist_os_name = base::ohos::BaseOsName();
  std::string dist_version = GetDistVersion();
  if (!dist_version.empty() && !dist_os_name.empty() &&
      dist_os_name != base_os_name) {
    base::StringAppendF(&ohos_fullname_str, "; %s %s", dist_os_name.c_str(),
                        dist_version.c_str());
  }
  return ohos_fullname_str;
}

void SetProductString(std::string& user_agent) {
  std::string product_string = "";

  if (!is_compatible_type_setted) {
    compatible_device_type = base::ohos::CompatibleDeviceType();
    is_compatible_type_setted = true;
  }

  base::StringAppendF(&product_string, " ArkWeb/%s", ARKWEB_VERSION);
  if (base::ohos::IsMobileDevice()) {
    product_string += " Mobile";
  } else if (base::ohos::IsTabletDevice() &&
             (compatible_device_type == "Phone")) {
    product_string += " Mobile";
  } else if (base::ohos::IsPcDevice() && (compatible_device_type == "Phone")) {
    product_string += " Mobile";
  }

  base::StringAppendF(&user_agent, "%s", product_string.c_str());
}
#endif  // ARKWEB_USERAGENT

}  // namespace content
